{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "1d818bde",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "=====================\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "// 可以用foreach遍历的类都是实现了迭代器\n",
    "\n",
    "// 接口:IEnumerator,IEnumerable\n",
    "// 命名空间: using System.Collections;\n",
    "// 可以通过同时继承IEnumerable和IEnumerator实现其中的方法 \n",
    "class MyList : IEnumerable, IEnumerator{\n",
    "    private int[] list;\n",
    "    public MyList() {\n",
    "        this.list = new int[] { 1, 2, 3, 4, 5, 6 };\n",
    "    }\n",
    "\n",
    "    public IEnumerator GetEnumerator() {\n",
    "        this.Reset();\n",
    "        return this;\n",
    "    }\n",
    "\n",
    "    public object Current {\n",
    "        get { return this.list[this.position]; }\n",
    "    }\n",
    "\n",
    "    private int position = -1; //从-1开始的光标\n",
    "\n",
    "    public bool MoveNext() {\n",
    "        this.position += 1;\n",
    "        return this.position < list.Length;\n",
    "    }\n",
    "\n",
    "    public void Reset() {\n",
    "        this.position = -1;\n",
    "    }\n",
    "}\n",
    "\n",
    "MyList list = new MyList();\n",
    "\n",
    "//1. 先获取in后面这个对象的IEnumerator,会调用其中的GetEnumerator,同时调用Reset重置游标\n",
    "//2. 执行IEnumerator对象的MoveNext下一个位置,只要返回值是true 就会得到Current复制给item. 直到返回值为false\n",
    "foreach (int item in list) {\n",
    "    Console.WriteLine(item);\n",
    "}\n",
    "\n",
    "Console.WriteLine(\"=====================\");\n",
    "\n",
    "foreach (int item in list) {\n",
    "    Console.WriteLine(item);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "9830422f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "=====================\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "// 使用yield return 语法糖实现迭代器 \n",
    "// 关键接口: IEnumerable\n",
    "// 命名空间: using System.Collections;\n",
    "// 自定义类独实现接口中的GetEnumerator即可\n",
    "\n",
    "class MyList : IEnumerable {\n",
    "    private int[] list;\n",
    "    public MyList() {\n",
    "        this.list = new int[] { 1, 2, 3, 4, 5, 6 };\n",
    "    }\n",
    "\n",
    "    public IEnumerator GetEnumerator() {\n",
    "        for (int i = 0; i < list.Length; i++) {\n",
    "            //yield 配合迭代器使用,可以理解为暂时返回,保留当前状态. 本质上遇到yield return 自动生成MoveNext等函数\n",
    "            yield return list[i];\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "MyList list = new MyList();\n",
    "foreach(int item in list) {\n",
    "    Console.WriteLine(item);\n",
    "}\n",
    "\n",
    "Console.WriteLine(\"=====================\");\n",
    "\n",
    "foreach (int item in list) {\n",
    "    Console.WriteLine(item);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "9ce51792",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12\n",
      "34\n",
      "56\n"
     ]
    }
   ],
   "source": [
    "// 使用yield return 语法糖为泛型类实现迭代器\n",
    "\n",
    "class MyList<T> : IEnumerable {\n",
    "    private T[] array;\n",
    "\n",
    "    public MyList(params T[] array) {\n",
    "        this.array = array;\n",
    "    }\n",
    "    public IEnumerator GetEnumerator() {\n",
    "        for (int i = 0; i < this.array.Length; i++) {\n",
    "            yield return this.array[i];\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "MyList<string> list = new MyList<string>(\"12\",\"34\",\"56\");\n",
    "\n",
    "foreach(string item in list){\n",
    "    Console.WriteLine(item);\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "polyglot-notebook"
  },
  "polyglot_notebook": {
   "kernelInfo": {
    "defaultKernelName": "csharp",
    "items": [
     {
      "aliases": [],
      "name": "csharp"
     }
    ]
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
